#coding: utf8
#Pruebas de la clase Jugador inteligente

from jugador_inteligente import JugadorInteligente
from Carta import Carta

def prueba_constructor():
	jugador1 = JugadorInteligente(0,"Juan")
	assert isinstance(jugador1,JugadorInteligente)
	assert jugador1.obtener_mano() == [[],[],[],[]]
	assert jugador1.obtener_nombre_jugador() == "Juan"
	assert jugador1.obtener_id_jugador() == 0
	assert jugador1.obtener_cartas_levantadas() == [[],[],[],[]]

def prueba_obtener_cantidad_cartas_en_mano():
	jugador1 = JugadorInteligente(0,"Juan")
	#Cuando se crea un jugador la cantidad de cartas en mano es 0
	assert jugador1.obtener_cantidad_cartas_en_mano()==0
	#Jugador recibe una carta
	jugador1.recibir_carta(Carta(12,Carta.PICAS))
	assert jugador1.obtener_cantidad_cartas_en_mano()==1
	
def prueba_recibir_carta():
	jugador1 = JugadorInteligente(0,"Juan")
	#si es de corazones la guarda en la primer sub-lista
	jugador1.recibir_carta(Carta(1,0))
	assert jugador1.obtener_mano() == [[Carta(1,0)],[],[],[]]
	#si es de diamantes en la segunda
	jugador1.recibir_carta(Carta(5,1))
	assert jugador1.obtener_mano() == [[Carta(1,0)],[Carta(5,1)],[],[]]
	#si es de picas en la tercera
	jugador1.recibir_carta(Carta(8,2))
	assert jugador1.obtener_mano() == [[Carta(1,0)],[Carta(5,1)],[Carta(8,2)],[]]
	#si es de treboles en la cuarta
	jugador1.recibir_carta(Carta(13,3))
	assert jugador1.obtener_mano() == [[Carta(1,0)],[Carta(5,1)],[Carta(8,2)],[Carta(13,3)]]
	
def crear_lista_de_13_cartas():
	'''Funcion auxiliar para las pruebas. Devuelve una lista de cartas inglesas'''
	return [Carta(12,0),Carta(1,0),Carta(5,0),Carta(8,1),Carta(13,1),Carta(2,1),Carta(4,1),Carta(5,2),Carta(11,2),Carta(9,2),Carta(2,2),Carta(1,3),Carta(2,3)]
	
def prueba_ordenar_cartas():
	#Creación
	jugador = JugadorInteligente(2,"Jorge")
	cartas = [Carta(12,Carta.CORAZONES),Carta(1,Carta.CORAZONES),Carta(10,Carta.CORAZONES),Carta(5,Carta.CORAZONES),Carta(6,Carta.CORAZONES)]
	cartas_ordenadas=[Carta(5,Carta.CORAZONES),Carta(6,Carta.CORAZONES),Carta(10,Carta.CORAZONES),Carta(12,Carta.CORAZONES),Carta(1,Carta.CORAZONES)]
	#Prueba
	jugador.ordenar_cartas(cartas)
	#La lista "carta" tiene que ser igual a la lista cartas_ordenadas
	assert cartas==cartas_ordenadas
		
#Recibir cartas pasadas no es más que recibir carta * 3

def prueba_jugar_la_mas_alta_la_mas_baja_y_especifica():
	jugador = JugadorInteligente(2,"Jorge")
	cartas = crear_lista_de_13_cartas()
	for carta in cartas:
		jugador.recibir_carta(carta)
	mano = jugador.obtener_mano()
	corazones = mano[0]
	assert jugador.jugar_la_mas_alta(corazones)	== Carta(1,0)
	assert jugador.jugar_la_mas_baja(corazones) == Carta(5,0)
	assert jugador.jugar_carta_especifica(Carta(2,1)) == Carta(2,1)

def prueba_reconocer_maxima_carta():
	jugador = JugadorInteligente(2,"Jorge")
	cartas = [Carta(3,2),Carta(1,0),Carta(13,2),Carta(12,2)]
	assert jugador.reconocer_maxima_carta(cartas) == Carta(13,2)
		
def prueba_jugar_baja_inmediata():
	jugador = JugadorInteligente(2,"Jorge")
	cartas=[]
	for nro_carta in xrange(1,13):
		cartas.append(Carta(nro_carta,Carta.PICAS))
	for carta in cartas:
		jugador.recibir_carta(carta)
		
	cartas_jugadas = [Carta(8,Carta.PICAS),Carta(1,Carta.CORAZONES),Carta(13,Carta.PICAS)]
	# Debe jugar la carta que se acerque (por debajo) más a 13, del palo picas
	assert (jugador.jugar_baja_inmediata(cartas_jugadas)).obtener_numero()==12 #Sabiendo que tiene todas las cartas del palo picas
	
def prueba_un_jugador_pretende_la_luna():
	jugador = JugadorInteligente(2,"Jorge")
	jugador.cartas_levantadas = [[],[],[Carta(1,Carta.CORAZONES),Carta(12,Carta.CORAZONES),Carta(13,Carta.CORAZONES)],[]]
	#En la documentacion se aclara que el metodo debe utilizarse a partir de la 9na mano en adelante
	excepcion_nro_jugada_atrapada=False
	try:
		jugador.un_jugador_pretende_la_luna(2)
	except ValueError:
		excepcion_nro_jugada_atrapada=True
	assert excepcion_nro_jugada_atrapada
	
	#La cantidad de cartas especiales de los jugadores no es mayor o igual a la cantidad jugadas
	assert not jugador.un_jugador_pretende_la_luna(9) 
	#La cantidad de cartas especiales de un jugador es mayor o igual a la cantidad de jugadas
	cartas_corazones=[]
	for nro in xrange(1,14):
		cartas_corazones.append(Carta(nro,Carta.CORAZONES))
	jugador.cartas_levantadas=[[],[Carta(12,Carta.PICAS)],cartas_corazones,[]]
	
	assert jugador.un_jugador_pretende_la_luna(9)
	
	
	
	
def prueba_jugar_palo_con_menos_cartas():
	jugador = JugadorInteligente(2,"Jorge")
	cartas = crear_lista_de_13_cartas()
	for carta in cartas:
		jugador.recibir_carta(carta)
	#hay 3 de corazones, 4 de diamantes, 4 de picas y 2 de treboles
	#Por lo tanto debería jugar la carta mas alta de tréboles
	assert jugador.jugar_palo_con_menos_cartas() == Carta(1,3)
	
def prueba_tiene_palo():
	jugador = JugadorInteligente(2,"Jorge")
	cartas = [Carta(2,2),Carta(3,0)]
	for carta in cartas:
		jugador.recibir_carta(carta)
	assert jugador.tiene_palo(2) and jugador.tiene_palo(0)
	assert not (jugador.tiene_palo(1) and jugador.tiene_palo(3))
	
def prueba_hay_cartas_especiales():
	jugador = JugadorInteligente(2,"Jorge")
	cartas1 = [Carta(2,2),Carta(3,0)]
	cartas2 = [Carta(1,2),Carta(4,1)]
	cartas3 = [Carta(12,2),Carta(4,3)]
	assert jugador.hay_cartas_especiales(cartas1) and jugador.hay_cartas_especiales(cartas3)
	assert not jugador.hay_cartas_especiales(cartas2)
	
def prueba_devolver_cartas_a_pasar():
	#Devuelve las 3 cartas del palo que menos cartas tenga
	jugador = JugadorInteligente(2,"Jorge")
	cartas = crear_lista_de_13_cartas()
	for carta in cartas:
		jugador.recibir_carta(carta)
	# hay 3 de corazones, 4 de diamantes, 4 de picas y 2 de treboles
	#debería devolver las 2 de tréboles y la más alta de corazones
	assert jugador.devolver_cartas_a_pasar(2) == [Carta(1,3),Carta(2,3),Carta(1,0)]
def prueba_conocer_jugada():
	jugador = JugadorInteligente(2,"Jorge")
	cartas_jugadas=[Carta(1,Carta.CORAZONES),Carta(12,Carta.PICAS),Carta(13,Carta.TREBOLES),Carta(11,Carta.DIAMANTES)]
	id_jugador_que_levanto=3
	id_primer_jugador=0
	assert jugador.cartas_levantadas==[[],[],[],[]]
	jugador.conocer_jugada(cartas_jugadas, id_primer_jugador, id_jugador_que_levanto)
	#Verifica que se hayan guardado las cartas especiales que levanto el jugador de ID 3 en su respectiva lista
	assert jugador.cartas_levantadas==[[],[],[],[Carta(1,Carta.CORAZONES),Carta(12,Carta.PICAS)]]
	
def prueba_jugar_carta():
	sur = JugadorInteligente(0,"Sur")
	cartas=[Carta(12,Carta.PICAS),Carta(10,Carta.TREBOLES),Carta(3,Carta.CORAZONES),Carta(6,Carta.DIAMANTES),Carta(2,Carta.TREBOLES),Carta(2,Carta.DIAMANTES),Carta(1,Carta.CORAZONES),Carta(1,Carta.CORAZONES)]
	for carta in cartas:
		sur.recibir_carta(carta)
	#Como es la primera mano y es el primero juega el 2 de treboles
	assert sur.jugar_carta(1, 1, [], False)==Carta(2,Carta.TREBOLES) 
	assert sur.obtener_cantidad_cartas_en_mano()==len(cartas)-1 #Se le quito una carta	
	
	#Juega una carta en la primer jugada ya habiendose jugado el 2 de treboles y teniendo una carta del palo Trebol
	cantidad_cartas_ant=sur.obtener_cantidad_cartas_en_mano()
	carta=sur.jugar_carta(2,1,[Carta(2,Carta.TREBOLES)],False)
	cantidad_cartas_post=sur.obtener_cantidad_cartas_en_mano()
	assert carta.obtener_palo()==Carta.TREBOLES
	assert cantidad_cartas_post==cantidad_cartas_ant-1
	
	#Juega una carta en la primer jugada sin tener una carta del palo Trebol
	cantidad_cartas_ant=sur.obtener_cantidad_cartas_en_mano()
	carta=sur.jugar_carta(3,1,[Carta(2,Carta.TREBOLES)],False)
	cantidad_cartas_post=sur.obtener_cantidad_cartas_en_mano()
	assert carta!=Carta(12,Carta.PICAS) #No puede haber jugado la q de picas
	assert carta.obtener_palo()!=Carta.CORAZONES #No puede haber jugado un corazon
	assert cantidad_cartas_post==cantidad_cartas_ant-1
	
	#Inicia una jugada (Distinta de 1) cuando aun no se jugaron corazones
	cantidad_cartas_ant=sur.obtener_cantidad_cartas_en_mano()
	carta=sur.jugar_carta(1,2,[],False)
	cantidad_cartas_post=sur.obtener_cantidad_cartas_en_mano()
	assert carta.obtener_palo()!=Carta.CORAZONES #No debe jugar un corazon
	assert cantidad_cartas_post==cantidad_cartas_ant-1
	
def pruebas_jugador():
	print "Pruebas jugador inteligente \n\r"
	for prueba in (
	prueba_constructor,
	prueba_obtener_cantidad_cartas_en_mano,
	prueba_recibir_carta,
	prueba_ordenar_cartas,
	prueba_jugar_la_mas_alta_la_mas_baja_y_especifica,
	prueba_reconocer_maxima_carta,
	prueba_jugar_baja_inmediata,
	prueba_tiene_palo,
	prueba_hay_cartas_especiales,
	prueba_jugar_palo_con_menos_cartas,
	prueba_devolver_cartas_a_pasar,
	prueba_devolver_cartas_a_pasar,
	prueba_conocer_jugada,
	prueba_jugar_carta
	):
		print (prueba.__name__ + ": "),
		prueba()
		print "OK"
		
pruebas_jugador()
